// go1.18.1 源码 time 库


package main
// time包提供了时间的显示和测量用的函数。日历的计算采用的是公历。
import (
	"fmt"
	"time"
)

func main()  {
	// 时间操作
	timeMain()
	// 月份操作
	monthMain()
	// 星期操作
	weekdayMain()
	// 整数纳秒操作
	durationMain()
	// 时间和纳秒操作
	timeDurationMain()
	// 计时器
	timeTimerManin()
	// 定时器
	timeTickerMain()
}

// 时间操作
func timeMain()  {
	// 给定位置相应区域的时间，返回 "2022-11-24 11:01:30 +0000 UTC" 格式时间
	t := time.Date(2022,time.November,24,11,1,30,0,time.UTC)
	t1 := time.Date(2021,time.November,24,11,15,30,0,time.UTC)
	t2 := time.Date(2022,time.November,24,11,15,30,0,time.UTC)
	t4 := time.Date(1,time.January,1,0,0,0,0,time.UTC)
	t5 := time.Date(1,time.January,1,1,1,1,1,time.UTC)


	// t 时间是否在 t1 之后
	timeAfterBool := t.After(t1)
	fmt.Println(timeAfterBool)

	// t2 时间是否在 t 之前
	timeBeforeBool := t2.Before(t2)
	fmt.Println(timeBeforeBool)

	// t 时间是否和 t1 相等
	timeEqualBoll := t.Equal(t1)
	fmt.Println(timeEqualBoll)

	// t4 是否是零值
	timeIsZeroBool := t4.IsZero()
	fmt.Println(timeIsZeroBool)

	// 返回 t 的年月日
	timeYear,timeMonth,timeDay := t.Date()
	fmt.Println(timeYear,timeMonth,timeDay)

	// 返回 t 的年份
	timeYearInt := t.Year()
	fmt.Println(timeYearInt)

	// 返回 t 的月份
	timeMonthMonth := t.Month()
	fmt.Println(timeMonthMonth)

	// 返回 t 的天
	timeDayInt := t.Day()
	fmt.Println(timeDayInt)

	// 返回 t 的星期
	timeWeekdayWeekday := t.Weekday()
	fmt.Println(timeWeekdayWeekday)

	// 返回 t 的年和周数
	timeISOWeekYear,timeISOWeekWeek := t.ISOWeek()
	fmt.Println(timeISOWeekYear,timeISOWeekWeek)

	// 返回 t 的小时，分钟，秒
	timeHourInt,timeMinInt,timeSecInt := t.Clock()
	fmt.Println(timeHourInt,timeMinInt,timeSecInt)

	// 返回 t 小时
	timeHoursInt := t.Hour()
	fmt.Println(timeHoursInt)

	// 返回 t 分钟
	timeSecsInt := t.Minute()
	fmt.Println(timeSecsInt)

	// 返回 t 秒
	timeSecondsInt := t.Second()
	fmt.Println(timeSecondsInt)

	// 返回 t 纳秒
	timeNanosecondsInt := t.Nanosecond()
	fmt.Println(timeNanosecondsInt)

	// 返回 t 中第多少天
	timeYearDayInt := t.YearDay()
	fmt.Println(timeYearDayInt)

	// 两个时间相减，返回纳秒计数
	timeSub := t5.Sub(t4)
	fmt.Println(timeSub)

	// 返回自 t 以来经过的时间
	timeSince := time.Since(t)
	fmt.Println(timeSince)

	// 返回直到 t 持续的时间
	timeUtil := time.Until(t)
	fmt.Println(timeUtil)

	// 日期相加
	years := 1
	months := 1
	days := 1
	timeAddDate := t5.AddDate(years,months,days)
	fmt.Println(timeAddDate)

	// 返回当前的本地时间
	timeNow := time.Now()
	fmt.Println(timeNow)

	// 	返回 UTC 时间
	timeUTC := t.UTC()
	fmt.Println(timeUTC)

	// 返回 本地时间
	timeLocal := t.Local()
	fmt.Println(timeLocal)

	// 返回 t 相关的时区
	timeLocation := t.Location()
	fmt.Println(timeLocation)

	// 返回痛与爱时间瞬间 t 的副本，并将位置设置为本地
	var location *time.Location
	location = timeLocation
	timeIn := t.In(location)
	fmt.Println(timeIn)

	// 返回 计算在 t 生效的时区，以及 UTC 以东的偏移量(单位秒)
	timeZoneName,timeZoneOffset := t.Zone()
	fmt.Println(timeZoneName,timeZoneOffset)

	// 返回 t 的时间戳，单位为秒
	timeUnix := t.Unix()
	fmt.Println(timeUnix)

	// 返回时间戳，时区为 UTC ，单位为毫秒
	timeUnixMilli := t.UnixMilli()
	fmt.Println(timeUnixMilli)

	// 返回 t 的时间戳，单位为毫秒
	timeUnixMicro := t.UnixMicro()
	fmt.Println(timeUnixMicro)

	// 返回 t 的时间戳，单位为纳秒
	timeUnixNano := t.UnixNano()
	fmt.Println(timeUnixNano)

	// 实现二进制编码，BinaryMarshaler接口
	timeMarshalBinary,_ := t.MarshalBinary()
	fmt.Println(timeMarshalBinary)

	// 实现二进制解码，BinaryUnmarshaler接口
	t5.UnmarshalBinary(timeMarshalBinary)
	fmt.Println(t5)

	// 实现 GobEncoder 编码接口
	timeGobEncode,_ := t.GobEncode()

	// 实现 GobDecode 解码接口
	t2.GobDecode(timeGobEncode)
	fmt.Println(t2)

	// 实现 json 编码处理接口
	timeMarshalJSON,_ := t.MarshalJSON()

	// 实现 json 解码处理接口
	t.UnmarshalJSON(timeMarshalJSON)
	fmt.Println(t)

	// 实现编码 TextMarshaler 接口
	timeMarshalText,_ := t.MarshalText()

	// 实现解码 TextUnmarshaler 接口
	t.UnmarshalText(timeMarshalText)
	fmt.Println(t)

	// 返回给定 Unix 时间对应的本地时间,秒，纳秒
	timeUnixTime := time.Unix(1669287690,30000000000)
	fmt.Println(timeUnixTime)

	// 返回给定 Unix 时间对应的本地时间,毫秒
	timeunixMilliTime := time.UnixMilli(16692876900000)
	fmt.Println(timeunixMilliTime)

	// 是否是 DST 时间
	timeIsDST := t.IsDST()
	fmt.Println(timeIsDST)

	// 返回将 t 四舍五入到 duration 的倍数结果
	var duration time.Duration
	duration = 1669287690000000000
	timeTruncate := t.Truncate(duration)
	fmt.Println(timeTruncate)

	// 返回将 t 四舍五入到 duration 的最近倍数结果
	timeRound := t.Round(duration)
	fmt.Println(timeRound)

	// 返回时间字符串
	timeString := t.String()
	fmt.Println(timeString)

	// 返回时间字符串,以，隔开
	timeGoString := t.GoString()
	fmt.Println(timeGoString)

	// 返回固定格式的字符串
	timeFormat := time.Now().Format("2006-01-02 03:04:05")
	fmt.Println(timeFormat)

	// 返回固定格式的字符串
	var b []byte
	timeAppendFormat := time.Now().AppendFormat(b,"2006-01-02 03:04:05")
	fmt.Println(string(timeAppendFormat))

	// 解析一个格式化的时间字符串并返回它代表的时间
	// layout规定了参考格式
	timeParse,_ := time.Parse("2006 Jan 02 15:04:05","2019 Feb 07 12:15:29.843443443")
	fmt.Println(timeParse)

	// 类似Parse但有两个重要的不同之处
	// 第一，当缺少时区信息时，Parse将时间解释为UTC时间，而ParseInLocation将返回值的Location设置为loc
	// 第二，当时间字符串提供了时区偏移量信息时，Parse会尝试去匹配本地时区，而ParseInLocation会去匹配loc
	timeParseInLocation,_  := time.ParseInLocation("2006 Jan 02 15:04:05","2019 Feb 07 12:15:29.843443443",t.Location())
	fmt.Println(timeParseInLocation)

	// 解析一个时间段字符串
	// 一个时间段字符串是一个序列，每个片段包含可选的正负号、十进制数、可选的小数部分和单位后缀，如"300ms"、"-1.5h"、"2h45m"
	// 合法的单位有"ns"、"us" /"µs"、"ms"、"s"、"m"、"h"
	timeParseDurations,_ := time.ParseDuration("2006 Jan 02 15:04:05")
	fmt.Println(timeParseDurations)


}

// 月份操作
func monthMain()  {
	var month time.Month
	month = 1

	// 返回月份的英文名称
	monthString := month.String()
	fmt.Println(monthString)
}

// 星期操作
func weekdayMain()  {
	var weekday time.Weekday
	weekday = 4

	// 返回星期的英文名称
	weekdayString := weekday.String()
	fmt.Println(weekdayString)

}

func durationMain()  {
	// 返回持续时间的字符串
	var duration time.Duration
	duration = 553445345933344
	timeDurationString := duration.String()
	fmt.Println(timeDurationString)

	// 纳秒持续时间最为整数纳秒基计数返回
	timeNanosecondsInt64 := duration.Nanoseconds()
	fmt.Println(timeNanosecondsInt64)

	// 微秒持续时间最为整数纳秒基计数返回
	timeMicrosecondsInt64 := duration.Microseconds()
	fmt.Println(timeMicrosecondsInt64)

	// 毫秒持续时间最为整数纳秒基计数返回
	timeMillisecondsInt64 := duration.Milliseconds()
	fmt.Println(timeMillisecondsInt64)

	// 以浮点 秒 数返回持续时间
	timeSecondFloat64 := duration.Seconds()
	fmt.Println(timeSecondFloat64)

	// 以浮点 分钟 返回持续时间
	timeMinutesFloat64 := duration.Minutes()
	fmt.Println(timeMinutesFloat64)

	// 以浮点 小时 返回持续时间
	timeHourFloat64 := duration.Hours()
	fmt.Println(timeHourFloat64)

	// duration 向零舍入到 duration2 的倍数结果
	// 若 duration2 <= 0 ,则返回 duration 不变
	var duration2 time.Duration
	duration = 9
	duration2 = 4
	// 9 - 9 % 4
	timeTruncateDuration := duration.Truncate(duration2)
	fmt.Println(timeTruncateDuration)

	// 舍入返回将 duration 四舍五入到最近 duration2 的倍数结果
	duration = 10
	duration2 = 4
	timeRoundDuration := duration.Round(duration2)
	fmt.Println(timeRoundDuration)

}

// 时间和纳秒操作
func timeDurationMain() {
	t := time.Date(1,time.January,1,0,0,0,0,time.UTC)
	var duration time.Duration
	duration = 100000000000

	// 时间和纳秒相加
	timeDurationAdd := t.Add(duration)
	fmt.Println(timeDurationAdd)
}

// 计时器
func timeTimerManin()  {
	// 创建一个新的计时器
	timeTimer := time.NewTimer(1000000000)

	// 停止计时
	timeTimerStopBool := timeTimer.Stop()
	fmt.Println(timeTimerStopBool)

	// 重置计时器
	timeTimerResetBool := timeTimer.Reset(10000)
	fmt.Println(timeTimerResetBool)

	// 等待持续时间，在通道中发送时间
	time.After(100000)

	// 等待持续时间，在 goroutine 中调用函数
	time.AfterFunc(1000,timeTimerManin)
}

// 定时器
func timeTickerMain()  {
	// 产生一个新的定时器
	timeTicker := time.NewTicker(1000000000)

	// 停止定时器
	timeTicker.Stop()

	// 重设定时器
	timeTicker.Reset(10000)

	// 新的定时器
	time.Tick(10000)
}

// 时区
func timeLocationMain() {
	// 返回给定名称的位置
	timeLocation,_ := time.LoadLocation("UTC")

	// 返回时区信息中描述性名称
	timeLocationString := timeLocation.String()
	fmt.Println(timeLocationString)

	// 返回一个位置，该位置使用给定的区域的名称和偏移量(偏移量的单位为秒)
	time.FixedZone("UTC",10000)


}
